package com.kuaimacode.kframework.api.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.kuaimacode.kframework.component.AliPushService;
import com.kuaimacode.kframework.component.AppletsPushService;
import com.kuaimacode.kframework.enums.AppletsPushTemplateEnum;
import com.kuaimacode.kframework.enums.UserTypeEnum;
import com.kuaimacode.kframework.exception.ErrorEnum;
import com.kuaimacode.kframework.exception.ServerInternalErrorException;
import com.kuaimacode.kframework.mybatis.mapper.sys.SysMessageMapper;
import com.kuaimacode.kframework.mybatis.models.sys.SysMessage;
import com.kuaimacode.kframework.mybatis.models.user.User;
import com.kuaimacode.kframework.weixin.AppletsTemplateData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author qinyong
 * @Title:
 * @Package com.kuaimacode.kframework.api.service
 * @Description: created by IntelliJ IDEA
 * @date 2019-03-15 21:51
 */
@Service
@Slf4j
public class SysMessageService extends ServiceImpl<SysMessageMapper, SysMessage> {

    @Autowired
    private AliPushService pushService;
    @Autowired
    private UserService userService;
    @Autowired
    AppletsPushService appletsPushService;

    /**
     * 查询用户的消息列表
     *
     * @param userId
     * @return
     */
    public List<SysMessage> getUserMessages(Long userId, Integer userType, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize, true, false, null);
        QueryWrapper<SysMessage> qryWrapper = new QueryWrapper<>();
        qryWrapper.eq("user_type", userType)
                .and(wrapper -> wrapper.eq("user_id", userId).or().eq("type", 0));
        qryWrapper.orderByDesc("create_at");
        return baseMapper.selectList(qryWrapper);
    }

    /**
     * 获取用户消息条数
     *
     * @param userId
     * @param userType
     * @return
     */
    public Integer getUserMessageCount(Long userId, Integer userType) {
        QueryWrapper<SysMessage> qryWrapper = new QueryWrapper<>();
        qryWrapper.eq("user_type", userType)
                .and(wrapper -> wrapper.eq("user_id", userId).or().eq("type", 0));
        return baseMapper.selectCount(qryWrapper);
    }

    /**
     * 获取用户未读消息条数
     *
     * @param userId
     * @param userType
     * @return
     */
    public Integer getUserUnReadMessageCount(Long userId, Integer userType) {
        QueryWrapper<SysMessage> qryWrapper = new QueryWrapper<>();
        qryWrapper.eq("user_type", userType).eq("is_read", 0)
                .and(wrapper -> wrapper.eq("user_id", userId).or().eq("type", 0));
        return baseMapper.selectCount(qryWrapper);
    }

    /**
     * 读取消息
     *
     * @param messageId
     * @return
     */
    public boolean readMessage(Long messageId, Long userId) {
        SysMessage message = new SysMessage();
        message.setIsRead((byte) 1);

        QueryWrapper<SysMessage> wrapper = new QueryWrapper<>();
        wrapper.eq("id", messageId).eq("user_id", userId);

        return baseMapper.update(message, wrapper) == 1;
    }

    /**
     * 保存消息
     *
     * @param title
     * @param subtitle
     * @param content
     * @param isPush
     * @return
     */
    public boolean saveMessage(String title, String subtitle, String content, boolean isPush, UserTypeEnum typeEnum, Long userId, Map<String, Object> custom) {
        SysMessage message = new SysMessage();
        message.setTitle(title);
        message.setSubtitle(subtitle);
        message.setContent(content);
        message.setUserId(userId);
        message.setUserType(typeEnum.getType());
        //业务消息
        message.setType((byte) 1);
        Date now = new Date();
        message.setCreateAt(now);
        message.setUpdateAt(now);
        baseMapper.insert(message);
        if (isPush) {
            pushService.pushByAlias(title, content, userId, custom);
        }
        return true;
    }

    /**
     * 保存消息
     *
     * @param title
     * @param subtitle
     * @param content
     * @param isPush
     * @param userId
     * @return
     */
    public boolean saveMessage(String title, String subtitle, String content, boolean isPush, Long userId, Map<String, Object> custom) {
        //查询用户类型
        User user = userService.getById(userId);
        if (user == null) {
            throw new ServerInternalErrorException(ErrorEnum.USER_NOT_EXISTS);
        }
        UserTypeEnum typeEnum = UserTypeEnum.USER;
        if (user.isOneMaster()) {
            typeEnum = UserTypeEnum.MASTER;
        }
        return this.saveMessage(title, subtitle, content, isPush, typeEnum, userId, custom);
    }

    /**
     * 保存消息
     *
     * @param title
     * @param content
     * @param isPush
     * @param userId
     * @return
     */
    public boolean saveMessage(String title, String content, boolean isPush, Long userId) {
        //查询用户类型
        User user = userService.getById(userId);
        if (user == null) {
            throw new ServerInternalErrorException(ErrorEnum.USER_NOT_EXISTS);
        }
        UserTypeEnum typeEnum = UserTypeEnum.USER;
        if (user.isOneMaster()) {
            typeEnum = UserTypeEnum.MASTER;
        }
        return this.saveMessage(title, "", content, isPush, typeEnum, userId, null);
    }

    /**
     * 保存消息
     *
     * @param title
     * @param content
     * @param isPush
     * @param userId
     * @return
     */
    public boolean saveMessage(String title, String content, boolean isPush, Long userId, Map<String, Object> custom) {
        return this.saveMessage(title, "", content, isPush, userId, custom);
    }

    /**
     * 保存消息
     *
     * @param title
     * @param content
     * @param isPush
     * @param typeEnum
     * @param userId
     * @return
     */
    public boolean saveMessage(String title, String content, boolean isPush, UserTypeEnum typeEnum, Long userId, Map<String, Object> custom) {
        return this.saveMessage(title, "", content, isPush, typeEnum, userId, custom);
    }

    /**
     * 保存并推送消息，使用小程序通用模板（app与小程序均推送）
     *
     * @param title
     * @param content
     * @param userId
     * @return
     */
    public void saveAndPushCommonMessage(String title, String content, Long userId) {
        Map<String, Object> appletsData = new HashMap<>();
        appletsData.put("keyword1", AppletsTemplateData.valueOf(content));
        this.saveAndPushMessage(title, content, userId, appletsData, AppletsPushTemplateEnum.COMMON_TEMPLATE);
    }

    public void saveAndPushMessage(String title, String content, Long userId, Object appletsData, AppletsPushTemplateEnum templateEnum) {
        this.saveAndPushMessage(title, "", content, userId, appletsData, templateEnum, null);
    }

    public void saveAndPushMessage(String title, String subtitle, String content, Long userId, Object appletsData, AppletsPushTemplateEnum templateEnum, Map<String, Object> custom) {
        //查询用户类型
        User user = userService.getById(userId);
        if (user == null) {
            throw new ServerInternalErrorException(ErrorEnum.USER_NOT_EXISTS);
        }
        UserTypeEnum typeEnum = UserTypeEnum.USER;
        if (user.isOneMaster()) {
            typeEnum = UserTypeEnum.MASTER;
        }
        SysMessage message = new SysMessage();
        message.setTitle(title);
        message.setSubtitle(subtitle);
        message.setContent(content);
        message.setUserId(userId);
        message.setUserType(typeEnum.getType());
        //业务消息
        message.setType((byte) 1);
        Date now = new Date();
        message.setCreateAt(now);
        message.setUpdateAt(now);
        baseMapper.insert(message);
        pushService.pushByAlias(title, content, userId, custom);

        if (StringUtils.isBlank(user.getFormId())) {
            log.warn("cannot find formId for userId: {}", userId);
            return;
        }

        int firstIndex = user.getFormId().indexOf(",");
        if (firstIndex < 0) {
            log.warn("cannot find formId for userId: {}, formId: {}", userId, user.getFormId());
            return;
        }

        //处理formid
        String formId = formId = user.getFormId().substring(0, firstIndex);
        User updateFormId = new User();
        updateFormId.setId(user.getId());
        updateFormId.setFormId(user.getFormId().replace(formId + ",", ""));
        userService.updateById(updateFormId);
        appletsPushService.pushMessage(userId, appletsData, formId, templateEnum);
    }
}
